package cn.schoolwow.quickdao.module.initial.flow.table;

import cn.schoolwow.quickdao.domain.QuickDAOConfig;
import cn.schoolwow.quickdao.domain.entity.Entity;
import cn.schoolwow.quickdao.domain.entity.Property;
import cn.schoolwow.quickdao.module.database.ddl.action.service.table.CreateTableFlow;
import cn.schoolwow.quickflow.domain.FlowContext;
import cn.schoolwow.quickflow.flow.BusinessFlow;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

public class AutomaticCreateTableFlow implements BusinessFlow {
    @Override
    public void executeBusinessFlow(FlowContext flowContext) throws Exception {
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);
        if(!quickDAOConfig.databaseOption.automaticCreateTable){
            flowContext.remark("跳过自动建表");
            return;
        }

        Collection<Entity> entityList = quickDAOConfig.databaseContext.entityMap.values();
        //先创建无外键关联的表
        for(Entity entity:entityList){
            if(!entity.foreignKeyProperties.isEmpty()){
                continue;
            }
            createEntityTable(entity, flowContext);
        }
        //再创建外键关联的表
        List<Entity> foreignKeyEntityList = new ArrayList<>();
        for(Entity entity:entityList){
            if(entity.foreignKeyProperties.isEmpty()){
                continue;
            }
            foreignKeyEntityList.clear();
            getForeignKeyEntityList(entity, foreignKeyEntityList, flowContext);
            for(Entity foreignKeyEntity:foreignKeyEntityList){
                createEntityTable(foreignKeyEntity, flowContext);
            }
            createEntityTable(entity, flowContext);
        }
    }

    @Override
    public String name() {
        return "自动建表";
    }

    private void getForeignKeyEntityList(Entity entity, List<Entity> foreignKeyEntityList, FlowContext flowContext){
        if(entity.foreignKeyProperties.isEmpty()){
            if(!foreignKeyEntityList.contains(entity)){
                foreignKeyEntityList.add(entity);
            }
            return;
        }
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);
        for(Property property:entity.foreignKeyProperties){
            Entity foreignKeyEntity = quickDAOConfig.getEntityByClassName(property.foreignKey.table().getName());
            //自关联
            if(foreignKeyEntity.tableName.equals(entity.tableName)){
                continue;
            }
            getForeignKeyEntityList(foreignKeyEntity, foreignKeyEntityList, flowContext);
        }
    }

    private void createEntityTable(Entity entity, FlowContext flowContext){
        QuickDAOConfig quickDAOConfig = flowContext.checkInstanceData(QuickDAOConfig.class);

        Entity databaseEntity = quickDAOConfig.getDatabaseEntityByTableName(entity.tableName);
        if (null == databaseEntity) {
            flowContext.startFlow(new CreateTableFlow())
                    .putTemporaryData("entity", entity)
                    .execute();
        }
    }
}
